package com.wx.commons.utils;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.SecureRandom;

public class FolderUtils {

    private static final String KEY = "iamkeyeeddzasdfs"; // 实际应用中应使用更安全的密钥生成方式

    private static final String source = "D:\\lib\\sources";

    private static final String dest = "D:\\lib\\dest";

    public static void m1(String[] args) {
        encrypt(source, dest);
    }

    public static void m2() {
        decrypt(dest, source);
    }

    public static void main(String[] args) {
    }

    public static void encrypt(String source, String dest) {
        File folder = new File(source);
        File[] files = folder.listFiles();
        for (File file : files) {
            String p1 = file.getAbsolutePath();
            String fileName = file.getName();
            String fName = stringTransformAscii(fileName);
            String p2 = dest + File.separator + fName;
            try {
                encryptFile(p1, p2);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void decrypt(String source, String dest) {
        File folder = new File(source);
        File[] files = folder.listFiles();
        for (File file : files) {
            String p1 = file.getAbsolutePath();
            String fileName = file.getName();
            String fName = asciiTransformString(fileName);
            String p2 = dest + File.separator + fName;
            try {
                decryptFile(p1, p2);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 字符串转换为Ascii
     *
     * @param value
     * @return
     */
    public static String stringTransformAscii(String value) {
        StringBuffer sbu = new StringBuffer();
        char[] chars = value.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            if (i != chars.length - 1) {
                sbu.append((int) chars[i]).append(",");
            } else {
                sbu.append((int) chars[i]);
            }
        }
        return sbu.toString();
    }

    /**
     * Ascii转换为字符串
     *
     * @param value
     * @return
     */
    public static String asciiTransformString(String value) {
        StringBuffer sbu = new StringBuffer();
        String[] chars = value.split(",");
        for (int i = 0; i < chars.length; i++) {
            sbu.append((char) Integer.parseInt(chars[i]));
        }
        return sbu.toString();
    }

    public static void encryptFile(String sourcePath, String encryptedPath) throws Exception {
        Cipher cipher = initCipher(Cipher.ENCRYPT_MODE);
        try (FileInputStream fis = new FileInputStream(sourcePath);
             FileOutputStream fos = new FileOutputStream(encryptedPath);
             CipherOutputStream cos = new CipherOutputStream(fos, cipher)) {

            byte[] buffer = new byte[1024];
            int read;
            while ((read = fis.read(buffer)) != -1) {
                cos.write(buffer, 0, read);
            }
        }
        System.out.println("加密完成");
    }

    public static void decryptFile(String encryptedPath, String decryptedPath) throws Exception {
        Cipher cipher = initCipher(Cipher.DECRYPT_MODE);
        try (FileInputStream fis = new FileInputStream(encryptedPath);
             CipherInputStream cis = new CipherInputStream(fis, cipher);
             FileOutputStream fos = new FileOutputStream(decryptedPath)) {

            byte[] buffer = new byte[1024];
            int read;
            while ((read = cis.read(buffer)) != -1) {
                fos.write(buffer, 0, read);
            }
        }
        System.out.println("解密完成");
    }

    private static Cipher initCipher(int mode) throws Exception {
        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        keyGenerator.init(128, new SecureRandom(KEY.getBytes()));
        SecretKey secretKey = keyGenerator.generateKey();
        byte[] codeFormat = secretKey.getEncoded();
        SecretKeySpec keySpec = new SecretKeySpec(codeFormat, "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(mode, keySpec);
        return cipher;
    }

}
